import { ref, reactive, watch, computed, nextTick, getCurrentInstance,toRefs, onMounted, onUnmounted } from 'vue';
import type { Ref } from 'vue';
import { sleep, getRect, sys } from '../../../libs/utils';
import { delay } from '../utils';
import { Enum } from '../env';
import useChat from './chat';
import useScroll from './scroll';
import useRefresher from './refresher';
import useVirtual from './virtual';

export interface hooksParam {
	useChatRecordMode?: boolean;
	chatRecordMoreOffset: string | number;
	autoHideKeyboardWhenChat?: boolean;
	autoAdjustPositionWhenChat?: boolean;
	chatAdjustPositionOffset: string | number;
	autoToBottomWhenChat?: boolean;
	showChatLoadingWhenReload?: boolean;
	chatLoadingMoreDefaultAsLoading?: boolean;
	watchTouchmove?: boolean;
	refresherThemeColor?: string;
	refresherImgStyle?: Record<string, any>;
	refresherTitleStyle?: Record<string, any>;
	refresherUpdateTimeStyle?: Record<string, any>;
	watchRefresherTouchmove?: boolean;
	refresherDefaultDuration: number | string;
	refresherCompleteDelay?: number | string;
	refresherCompleteDuration: number | string;
	refresherRefreshingScrollable?: boolean;
	refresherCompleteScrollable?: boolean;
	useCustomRefresher?: boolean;
	refresherFps: number | string;
	refresherMaxAngle?: number | string;
	refresherAngleEnableChangeContinued?: boolean;
	refresherDefaultText?: string | Record<string, any>;
	refresherPullingText?: string | Record<string, any>;
	refresherRefreshingText?: string | Record<string, any>;
	refresherCompleteText?: string | Record<string, any>;
	refresherGoF2Text?: string | Record<string, any>;
	refresherDefaultImg?: string;
	refresherPullingImg?: string;
	refresherRefreshingImg?: string;
	refresherCompleteImg?: string;
	refresherRefreshingAnimated?: boolean;
	refresherEndBounceEnabled?: boolean;
	refresherEnabled?: boolean;
	refresherThreshold?: number | string;
	refresherDefaultColor?: string;
	refresherBackground?: string;
	refresherFixedBackground?: string;
	refresherFixedBacHeight: number | string;
	refresherOutRate: number;
	refresherF2Enabled?: boolean;
	refresherF2Threshold?: number | string;
	refresherF2Duration: number | string;
	showRefresherF2?: boolean;
	refresherPullRate: number;
	refresherTimeText?: string;
	refresherVibrate?: boolean;
	refresherNoTransform?: boolean;
	useRefresherStatusBarPlaceholder?: boolean;
	nvueListIs: 'list' | 'waterfall' | 'scroller';
	nvueWaterfallConfig?: Record<string, any>;
	nvueBounce?: boolean;
	nvueFastScroll?: boolean;
	nvueListId?: string;
	nvueRefresherStyle?: Record<string, any>;
	nvuePagingEnabled?: boolean;
	hideNvueBottomTag?: boolean;
	offsetAccuracy?: number;
	lowerThreshold: number | string;
	usePageScroll?: boolean;
	scrollable?: boolean;
	showScrollbar?: boolean;
	scrollX?: boolean;
	scrollToTopBounceEnabled?: boolean;
	scrollToBottomBounceEnabled?: boolean;
	scrollWithAnimation?: boolean;
	scrollIntoView?: string;
	backToTopWithAnimate?: boolean;
	delay?: number | string;
	minDelay?: number | string;
	pagingStyle?: Record<string, any>;
	height?: string;
	width?: string;
	maxWidth?: string;
	bgColor?: string;
	pagingContentStyle?: Record<string, any>;
	autoHeight?: boolean;
	autoHeightAddition: number | string;
	defaultThemeColor?: string;
	fixed?: boolean;
	safeAreaInsetBottom?: boolean;
	useSafeAreaPlaceholder?: boolean;
	bottomBgColor?: string;
	topZIndex?: number;
	superContentZIndex?: number;
	contentZIndex?: number;
	f2ZIndex?: number;
	autoFullHeight?: boolean;
	watchTouchDirectionChange?: boolean;
	unit?: string;
	isFirstPageAndNoMore?: boolean;
	useVirtualList?: boolean;
	cellHeightMode?:string
	preloadPage?: number | string;
	fixedCellHeight?: number | string;
	virtualListCol?: number | string;
	virtualScrollFps?: number | string;
	forceCloseInnerList?:boolean
	virtualListData?:Array<any>
	virtualListPageSize?:number|string
	virtualItemIdKey?:string
}

export interface CommonState {
	refresherStatus: number;
	systemInfo: ReturnType<typeof sys>;
	isIos: boolean;
	wxsScrollTop: number;
	scrollEnable: boolean;
	superContentHeight: number;
	cleanAllTimeout: Function;
	cleanRefresherCompleteTimeout: Function;
	cleanRefresherEndTimeout: Function;
}

let refresherCompleteTimeout: number | undefined;
let refresherEndTimeout: number | undefined;

export const useCommon = (ctx: ReturnType<typeof getCurrentInstance>) => {
	const systemInfo = sys();

	// 清除timeout
	const _cleanTimeout = (timeout?: number) => {
		if (timeout) {
			clearTimeout(timeout);
			timeout = undefined;
		}
		return timeout;
	};

	// 清除refresherCompleteTimeout
	const cleanRefresherCompleteTimeout = () => {
		refresherCompleteTimeout = _cleanTimeout(refresherCompleteTimeout);
		// #ifdef APP-NVUE
		// _nRefresherEnd(false);
		// #endif
	};

	// 清除refresherEndTimeout
	const cleanRefresherEndTimeout = () => {
		refresherEndTimeout = _cleanTimeout(refresherEndTimeout);
	};

	const cleanAllTimeout = () => {
		cleanRefresherCompleteTimeout();
		cleanRefresherEndTimeout();
	};

	const commonState = reactive<CommonState>({
		systemInfo,
		//下拉刷新状态
		refresherStatus: Enum.Refresher.Default,
		isIos: systemInfo.platform === 'ios',
		wxsScrollTop: 0,
		scrollEnable: true,
		superContentHeight: 0,
		cleanAllTimeout,
		cleanRefresherCompleteTimeout,
		cleanRefresherEndTimeout
	});

	const cssSafeAreaInsetBottom = ref(-1);
	// 底部安全区域高度
	const safeAreaBottom = computed(() => {
		let safeAreaBottom = 0;
		// #ifdef APP-PLUS
		safeAreaBottom = commonState.systemInfo.safeAreaInsets?.bottom || 0;
		// #endif
		// #ifndef APP-PLUS
		safeAreaBottom = Math.max(cssSafeAreaInsetBottom.value, 0);
		// #endif
		return safeAreaBottom;
	});

	// 通过获取css设置的底部安全区域占位view高度设置bottom距离（直接通过systemInfo在部分平台上无法获取到底部安全区域）
	const getCssSafeAreaInsetBottom = async () => {
		const size = await getRect(ctx, '.e-scroll-view__safe-area-inset-bottom');
		cssSafeAreaInsetBottom.value = size.height || -1;
	};

	return {
		cssSafeAreaInsetBottom,
		safeAreaBottom,
		getCssSafeAreaInsetBottom,
		commonState,
		cleanRefresherCompleteTimeout,
		cleanRefresherEndTimeout
	};
};

export const useHooks = (option: Ref<hooksParam>, emit: ReturnType<typeof defineEmits>) => {
	const ctx = getCurrentInstance();
	
	// 聊天记录模式旋转180度style
	const chatRecordRotateStyle = computed(() => {
		let cellStyle;
		// 在vue中，直接将列表倒置，因此在vue的cell中，也直接写style="transform: scaleY(-1)"转回来即可。
		// #ifndef APP-NVUE
		cellStyle = option.value.useChatRecordMode ? { transform: 'scaleY(-1)' } : {};
		// #endif

		// 在nvue中，需要考虑数据量不满一页的情况，因为nvue中的list无法通过flex-end修改不满一页的起始位置，会导致不满一页时列表数据从底部开始，因此需要特别判断
		// 当数据不满一屏的时候，不进行列表倒置
		// #ifdef APP-NVUE
		cellStyle = option.value.useChatRecordMode ? { transform: option.value.isFirstPageAndNoMore ? 'scaleY(1)' : 'scaleY(-1)' } : {};
		// #endif

		return cellStyle;
	});
	// 是否是聊天记录列表并且有配置transform
	const isChatRecordModeHasTransform = computed(() => {
		return option.value.useChatRecordMode && chatRecordRotateStyle.value?.transform;
	});
	// 是否是聊天记录列表并且列表未倒置
	const isChatRecordModeAndNotInversion = computed(() => {
		return isChatRecordModeHasTransform.value && chatRecordRotateStyle.value?.transform === 'scaleY(1)';
	});
	// 是否是聊天记录列表并且列表倒置
	const isChatRecordModeAndInversion = computed(() => {
		return !!(isChatRecordModeHasTransform.value && chatRecordRotateStyle.value?.transform === 'scaleY(-1)');
	});

	watch(chatRecordRotateStyle, (v) => {
		emit('update:cellStyle', v);
		emit('cellStyleChange', v);

		// // 在聊天记录模式中，如果列表没有倒置并且当前是第一页，则需要自动滚动到最底部
		// nextTick(() => {
		// 	if (isChatRecordModeAndNotInversion.value) {
		// 		nextTick(async () => {
		// 			// 这里多次触发滚动到底部是为了避免在某些情况下，即使是在nextTick但是cell未渲染完毕导致滚动到底部位置不正确的问题
		// 			this._scrollToBottom(false);
		// 			await sleep(50);

		// 			this._scrollToBottom(false);
		// 			await sleep(50);
		// 			this._scrollToBottom(false);
		// 		});
		// 	}
		// });
	});

	const { cssSafeAreaInsetBottom, getCssSafeAreaInsetBottom, safeAreaBottom, commonState } = useCommon(ctx);
	const {
		scrollTop,
		oldScrollTop,
		scrollViewStyle,
		scrollViewInStyle,
		scrollViewElRef,
		finalScrollViewStyle,
		setAutoHeight,
		pageScrollTop,
		privateScrollWithAnimation,
		finalScrollWithAnimation,
		finalScrollTop,
		finalScrollable,
		scrollToTop,
		scrollToBottom,
		scrollIntoViewById,
		scrollIntoViewByNodeTop,
		scrollToY,
		scrollIntoViewByIndex,
		scrollIntoViewByView,
		updatePageScrollTop,
		updateScrollViewScrollTop,
		listTopAagElRef,
		refreshElRef,
		listBottomAagElRef,
		_onScrollToUpper,
		_onScrollToLower,
		// _scrollToBottom,
		_scrollIntoView,
		_scrollIntoViewByNodeTop,
		_scrollToY,
		finalLowerThreshold,
		checkScrolledToBottom,
		handleVueScroll,
		updatePrivateScrollWithAnimation,
		pagingContentElRef,
		updateCachedSuperContentHeight,
		wxsPageScrollTop,
		scrollTopChange
	} = useScroll(ctx, option, emit, commonState, isChatRecordModeAndInversion,() => scrollToViewCb(),() => getVirtualPlaceholderTopHeight());
	
	const {
		finalUseVirtualList,
		virtualCellHeight,
		virtualHeightCacheList,
		virtualPlaceholderTopHeight,
		virtualPlaceholderBottomHeight,
		_updateVirtualScroll,
		doInsertVirtualListItem,
		didUpdateVirtualListCell,
		didDeleteVirtualListCell,
		updateVirtualListRender,
		_virtualListInit,
		_checkVirtualListScroll,
	} = useVirtual(ctx, option, emit, commonState,oldScrollTop)
	const scrollToViewCb = () => {
		
		return {
			finalUseVirtualList:!!finalUseVirtualList.value,
			isCellFixed:option.value.cellHeightMode === Enum.CellHeightMode.Fixed,
			virtualCellHeight:virtualCellHeight.value,
			virtualHeightCacheList:virtualHeightCacheList.value
		}
	}
	const getVirtualPlaceholderTopHeight = () => {
		
		return virtualPlaceholderTopHeight.value
	}
	
	
	
	
	const refresherEnd = (status?:number,setRefresherCompleteTimeout?:Function) => {
		// 清除下拉刷新相关timeout
		commonState.cleanAllTimeout();
		// #ifndef APP-NVUE
		refresherEndTimeout = delay(() => {
			commonState.refresherStatus = status!;
		}, commonState.refresherStatus !== Enum.Refresher.Default && status === Enum.Refresher.Default ? option.value.refresherCompleteDuration : 0);
		
		refresherCompleteTimeout = setRefresherCompleteTimeout?.()
		
		// #endif
		// #ifdef APP-NVUE
	
		// 如果reload不需要自动展示下拉刷新view，则在complete duration结束后再把下拉刷新状态设置回默认
		refresherEndTimeout = delay(() => {
			commonState.refresherStatus = Enum.Refresher.Default;
		}, option.value.refresherCompleteDuration);
		// #endif
	};
	
	const { finalChatRecordMoreOffset, finalChatAdjustPositionOffset, chatRecordModeSafeAreaBottom, doChatRecordLoadMore, handleKeyboardHeightChange } = useChat(
		option,
		emit,
		safeAreaBottom,
		scrollToBottom
	);

	
	const {
		pullDownDisTimeStamp,
		privateRefresherEnabled,
		refresherThresholdUnitConverted,
		finalRefresherEnabled,
		finalRefresherThresholdPlaceholder,
		finalRefresherThreshold,
		finalRefresherF2Threshold,
		finalRefresherFixedBacHeight,
		finalRefresherThemeStyle,
		finalRefresherOutRate,
		finalRefresherPullRate,
		finalRefresherTransform,
		finalRefresherTriggered,
		showRefresher,
		refresherTransform,
		refresherRevealStackCount,
		refresherTriggered,
		isTouchmoving,
		customRefresherHeight,
		showCustomRefresher,
		doRefreshAnimateAfter,
		isRefresherInComplete,
		_onRestore,
		loading,
		_refresherEnd,
		refresherTransition,
		handleScrollViewBounce,
		endRefresh,
		updateCustomRefresherHeight,
		handleRefresh,
		finalRefresherDefaultStyle,
		handleListTouchstart,
		handleRefresherTouchstart,
		handleTouchDirectionChange,
		isTouchEnded,
		// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
		touchDisabled,
		refresherTouchstart,
		getFinalRefresherMoveDis,
		_emitTouchmove,
		oldTouchDirection,
		oldEmitedTouchDirection,
		disabledBounce,
		_refresherTouchmove,
		_refresherTouchend,
		// #endif
		refreshEnd,
		handleRefresherTouchmove,
		handleRefresherTouchend,
		renderPropScrollTop,
		wxsOnPullingDown,
		handleWxsPullingDownStatusChange,
		handleWxsPullingDown,
		wxsPropType,
		handlePropUpdate,
		showF2,
		f2Transform,
		f2ElRef,
		nF2Opacity,
		handleGoF2,
		_handleCloseF2,
		closeF2,
		doRefresherRefreshAnimate,
		_doRefresherLoad,
		_updateCustomRefresherHeight,
		// #ifdef APP-NVUE
		nLoadingMoreFixedHeight,
		finalNvueListIs,
		nWaterfallColumnCount,
		nWaterfallColumnWidth,
		nWaterfallColumnGap,
		nWaterfallLeftGap,
		nWaterfallRightGap,
		nViewIs,
		finalNvueSuperListIs,
		finalNvueRefresherEnabled,
		handleNVueScroll,
		nListRef,
		_nRefresherEnd,
		nRefresherLoading,
		_nOnRrefresh,
		_nOnPullingdown,
		_nDoRefresherEndAnimation,
		handleNVueLoadmore,
		_nGetWaterfallConfig
		// #endif
	} = useRefresher(ctx, option, emit, commonState,refresherEnd, oldScrollTop, pageScrollTop,doChatRecordLoadMore);
	
	

	



	const handleScroll = (e: { detail: { scrollTop: number; scrollHeight: number }; contentOffset: { y: number }; isDragging: boolean }) => {
		emit('scroll', e);
		// #ifndef APP-NVUE
		finalUseVirtualList.value && _updateVirtualScroll(scrollTop.value, oldScrollTop.value - e.detail.scrollTop);
		handleVueScroll(e);
		
		// #endif
		// #ifdef APP-NVUE
		handleNVueScroll(e);
		// #endif
	};

	const refresherThresholdUpdateTag = ref(0);

	const nFixFreezing = ref(false);
	// 设置nvue List的specialEffects
	const setSpecialEffects = (args: any) => {
		setListSpecialEffects(args);
	};
	// 与setSpecialEffects等效，兼容旧版本
	const setListSpecialEffects = (args: any) => {
		nFixFreezing.value = !!(args && Object.keys(args).length);
		if (commonState.isIos) {
			privateRefresherEnabled.value = 0;
		}
		!option.value.usePageScroll && nListRef.value?.setSpecialEffects?.(args);
	};
	// #ifdef APP-VUE
	let pageLaunched = false;
	// 当app长时间进入后台后进入前台，因系统内存管理导致app重新加载时，进行一些适配处理
	const handlePageLaunch = () => {
		// 首次触发不进行处理，只有进入后台后打开app重新加载时才处理
		if (pageLaunched) {
			// 解决在vue3+ios中，app ReLaunch时顶部下拉刷新展示位置向下偏移的问题
			// #ifdef VUE3
			refresherThresholdUpdateTag.value = 1;
			nextTick(() => {
				refresherThresholdUpdateTag.value = 0;
			});
			// #endif
			// 解决使用虚拟列表时，app ReLaunch时白屏问题
			_checkVirtualListScroll();
		}
		pageLaunched = true;
	};
	// #endif

	const finalPagingStyle = computed(() => {
		const pagingStyle = { ...(option.value?.pagingStyle || {}) };
		if (!commonState.systemInfo) return pagingStyle;

		if (option.value?.bgColor && !pagingStyle['background']) {
			pagingStyle['background'] = option.value.bgColor;
		}
		if (option.value?.height && !pagingStyle['height']) {
			pagingStyle['height'] = option.value.height;
		}
		if (option.value?.width && !pagingStyle['width']) {
			pagingStyle['width'] = option.value.width;
		}
		if (option.value.maxWidth && !pagingStyle['max-width']) {
			pagingStyle['max-width'] = option.value.maxWidth;
			pagingStyle['margin'] = '0 auto';
		}
		return pagingStyle;
	});

	// 滚动到顶部
	const handleToTop = () => {
		scrollToTop(option.value?.backToTopWithAnimate);
	};

	let active = false;

	watch(showRefresher, (v) => {
		active && customRefresherHeight.value === -1 && v && updateCustomRefresherHeight();
	});

	let isIosAndH5 = commonState.isIos;
	// #ifndef H5
	isIosAndH5 = false;
	// #endif

	watch(finalScrollTop, (v) => {
		renderPropScrollTop.value = v < 6 ? 0 : 10;
	});

	onMounted(() => {
		active = true;
		wxsPropType.value = new Date().getTime().toString();

		nextTick(async () => {
			// 初始化z-paging高度
			!option.value.usePageScroll && option.value.autoHeight && setAutoHeight();
			await sleep(100);
			// 更新fixed模式下z-paging的布局，主要是更新windowTop、windowBottom
			option.value.fixed &&
				nextTick(() => {
					commonState.systemInfo = sys();
				});
			// 更新缓存中z-paging整个内容容器高度
			updateCachedSuperContentHeight();
		});

		if (finalRefresherEnabled.value && option.value.useCustomRefresher) {
			nextTick(() => {
				isTouchmoving.value = true;
			});
		}
		// #ifndef APP-NVUE
		// 虚拟列表模式时，初始化数据
		finalUseVirtualList.value && _virtualListInit();
		// #endif

		// #ifndef APP-PLUS
		nextTick(() => {
			let delay = 0;
			// #ifdef H5 || MP
			delay = 100;
			// #endif
			// 非app平台中，获取css设置的底部安全区域占位view高度
			setTimeout(() => {
				getCssSafeAreaInsetBottom();
			}, delay);
		});
		// #endif
	});
	onUnmounted(() => {
		active = false;
		// 取消监听键盘高度变化事件（H5、百度小程序、抖音小程序、飞书小程序、QQ小程序、快手小程序不支持）
		// #ifndef H5 || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-KUAISHOU
		option.value.useChatRecordMode && uni.offKeyboardHeightChange(handleKeyboardHeightChange);
		// #endif
	});

	return {
		chatRecordRotateStyle,
		isChatRecordModeHasTransform,
		isChatRecordModeAndNotInversion,
		isChatRecordModeAndInversion,
		cssSafeAreaInsetBottom,
		getCssSafeAreaInsetBottom,
		safeAreaBottom,
		...toRefs(commonState),
		scrollTop,
		oldScrollTop,
		scrollViewStyle,
		scrollViewInStyle,
		scrollViewElRef,
		finalScrollViewStyle,
		setAutoHeight,
		pageScrollTop,
		privateScrollWithAnimation,
		finalScrollWithAnimation,
		finalScrollTop,
		finalScrollable,
		scrollToTop,
		scrollToBottom,
		scrollIntoViewById,
		scrollIntoViewByNodeTop,
		scrollToY,
		scrollIntoViewByIndex,
		scrollIntoViewByView,
		updatePageScrollTop,
		updateScrollViewScrollTop,
		listTopAagElRef,
		refreshElRef,
		listBottomAagElRef,
		_onScrollToUpper,
		_onScrollToLower,
		_scrollIntoView,
		_scrollIntoViewByNodeTop,
		_scrollToY,
		finalLowerThreshold,
		checkScrolledToBottom,
		handleVueScroll,
		updatePrivateScrollWithAnimation,
		pagingContentElRef,
		updateCachedSuperContentHeight,
		wxsPageScrollTop,
		scrollTopChange,
		pullDownDisTimeStamp,
		privateRefresherEnabled,
		refresherThresholdUnitConverted,
		finalRefresherEnabled,
		finalRefresherThresholdPlaceholder,
		finalRefresherThreshold,
		finalRefresherF2Threshold,
		finalRefresherFixedBacHeight,
		finalRefresherThemeStyle,
		finalRefresherOutRate,
		finalRefresherPullRate,
		finalRefresherTransform,
		finalRefresherTriggered,
		showRefresher,
		refresherTransform,
		refresherRevealStackCount,
		refresherTriggered,
		isTouchmoving,
		customRefresherHeight,
		showCustomRefresher,
		doRefreshAnimateAfter,
		isRefresherInComplete,
		_onRestore,
		loading,
		_refresherEnd,
		refresherTransition,
		handleScrollViewBounce,
		endRefresh,
		updateCustomRefresherHeight,
		handleRefresh,
		finalRefresherDefaultStyle,
		handleListTouchstart,
		handleRefresherTouchstart,
		handleTouchDirectionChange,
		isTouchEnded,
		// #ifndef APP-VUE || MP-WEIXIN || MP-QQ || H5
		touchDisabled,
		refresherTouchstart,
		getFinalRefresherMoveDis,
		_emitTouchmove,
		oldTouchDirection,
		oldEmitedTouchDirection,
		disabledBounce,
		_refresherTouchmove,
		_refresherTouchend,
		// #endif
		refreshEnd,
		handleRefresherTouchmove,
		handleRefresherTouchend,
		renderPropScrollTop,
		wxsOnPullingDown,
		handleWxsPullingDownStatusChange,
		handleWxsPullingDown,
		wxsPropType,
		handlePropUpdate,
		showF2,
		f2Transform,
		f2ElRef,
		nF2Opacity,
		handleGoF2,
		_handleCloseF2,
		closeF2,
		doRefresherRefreshAnimate,
		_doRefresherLoad,
		_updateCustomRefresherHeight,
		finalChatRecordMoreOffset,
		finalChatAdjustPositionOffset,
		chatRecordModeSafeAreaBottom,
		doChatRecordLoadMore,
		handleKeyboardHeightChange,
		// #ifdef APP-NVUE
		nLoadingMoreFixedHeight,
		finalNvueListIs,
		nWaterfallColumnCount,
		nWaterfallColumnWidth,
		nWaterfallColumnGap,
		nWaterfallLeftGap,
		nWaterfallRightGap,
		nViewIs,
		finalNvueSuperListIs,
		finalNvueRefresherEnabled,
		handleNVueScroll,
		nListRef,
		_nRefresherEnd,
		nRefresherLoading,
		_nOnRrefresh,
		_nOnPullingdown,
		_nDoRefresherEndAnimation,
		handleNVueLoadmore,
		_nGetWaterfallConfig,
		// #endif
		handleScroll,
		refresherThresholdUpdateTag,
		nFixFreezing,
		setSpecialEffects,
		// #ifdef APP-VUE
		handlePageLaunch,
		// #endif
		finalPagingStyle,
		handleToTop,
		isIosAndH5,
		// 虚拟列表
		virtualPlaceholderTopHeight,
		virtualPlaceholderBottomHeight,
		doInsertVirtualListItem,
		didUpdateVirtualListCell,
		didDeleteVirtualListCell,
		updateVirtualListRender
	};
};
